package com.sinping.qh.service.admin.impl;

import com.sinping.qh.api.support.*;
import com.sinping.qh.domain.common.BuildingDomain;
import com.sinping.qh.domain.lab.LaboratoryDomain;
import com.sinping.qh.domain.user.UserInfo;
import com.sinping.qh.domain.user.UserLaboratory;
import com.sinping.qh.dto.admin.ApiBuildingDto;
import com.sinping.qh.dto.auth.UserSessionDTO;
import com.sinping.qh.query.lab.BuildingQuery;
import com.sinping.qh.repository.mongo.BuildingReposity;
import com.sinping.qh.repository.mongo.lab.LaboratoryRepository;
import com.sinping.qh.repository.mongo.user.UserInfoRepository;
import com.sinping.qh.repository.mongo.user.UserLaboratoryRepository;
import com.sinping.qh.service.MongoManager;
import com.sinping.qh.service.admin.IBuildingService;
import com.sinping.qh.service.auth.ISessionService;
import com.sinping.qh.service.common.CommonDbConst;
import com.sinping.qh.utils.mapper.BeanMapper;
import com.sinping.qh.utils.mapper.JsonMapper;
import com.sinping.qh.utils.misc.IdGenerator;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 楼宇接口实现类
 *
 * @author Tiansx
 * @create 2018-05-29 13:54
 **/
@Service
public class BuildingImpl implements IBuildingService {

    @Autowired
    private BuildingReposity buildingReposity;
    @Autowired
    private UserInfoRepository userInfoRepository;
    @Qualifier("sessionServiceRedisImpl")
    @Autowired
    private ISessionService iSessionService;
    @Autowired
    MongoManager mongoManager;
    @Autowired
    UserLaboratoryRepository userLaboratoryRepository;
    @Autowired
    LaboratoryRepository laboratoryRepository;

    private final static Logger logger = LoggerFactory.getLogger(BuildingImpl.class);

    @Override
    public ResDto addBuilding(HttpServletRequest httpRequest, ApiBuildingDto apiBuildingDto) {
        /**
         * 获取当前用户id
         */
        String token = httpRequest.getHeader(Const.TOKEN_NAME);
        UserSessionDTO userSessionDTO = iSessionService.getSessionByToken(token);
        if (userSessionDTO == null) {
            return new ResDto(Const.PARAM_ERROR, "用户未登录");
        }

        //验证参数
        if (StringUtils.isBlank(userSessionDTO.getId())) {

            return new ResDto(Const.SERVER_ERROR, "获取用户id失败");
        }
        //设置创建人id
        apiBuildingDto.setCreateUserId(userSessionDTO.getId());

        if (StringUtils.isNotBlank(apiBuildingDto.getBuildingName())) {
           List<BuildingDomain>  buildingDomainList = buildingReposity.findAllByBuildingNameAndStatus(apiBuildingDto.getBuildingName(),CommonDbConst.DB_DELETE_NORMAL);
            for (BuildingDomain buildingDomainOne: buildingDomainList) {
                if (buildingDomainOne != null) {
                    //状态正常
                    if (CommonDbConst.DB_DELETE_NORMAL.equals(buildingDomainOne.getStatus())){
                        return new ResDto(Const.SERVER_ERROR, "楼宇名称已存在");
                    }

                }
            }



        }
        if (StringUtils.isNotBlank(apiBuildingDto.getCreateUserId())) {
            UserInfo one = userInfoRepository.findOne(apiBuildingDto.getCreateUserId());
            if (one == null) {
              return  new ResDto(Const.SERVER_ERROR,"创建人不存在");
            }
        }
        BuildingDomain buildingDomain = BeanMapper.map(apiBuildingDto, BuildingDomain.class);
        buildingDomain.setId(IdGenerator.uuid2());
        buildingDomain.setUpdateUserId(apiBuildingDto.getCreateUserId());
        //0:正常 1:逻辑删除
        buildingDomain.setStatus(CommonDbConst.DB_DELETE_NORMAL);
        buildingDomain.setGmtCreated(new Date());
        buildingDomain.setGmtModified(new Date());

        try {
            BuildingDomain save = buildingReposity.save(buildingDomain);
            if (save==null){
                return new ResDto(Const.SERVER_ERROR,"楼宇记录生成失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("生成楼宇信息异常：{}", e);
        }


        return new ResDto(Const.SUCCESS,"楼宇信息生成成功");
    }

    @Override
    public ResDto updateBuilding(HttpServletRequest httpRequest, ApiBuildingDto apiBuildingDto) {
        /**
         * 获取当前用户id
         */
        String token = httpRequest.getHeader(Const.TOKEN_NAME);
        UserSessionDTO userSessionDTO = iSessionService.getSessionByToken(token);
        if (userSessionDTO == null) {
            return new ResDto(Const.PARAM_ERROR, "用户未登录");
        }

        //验证参数
        if (StringUtils.isBlank(userSessionDTO.getId())) {

            return new ResDto(Const.SERVER_ERROR, "获取用户id失败");
        }
        //设置修改人id
        apiBuildingDto.setUpdateUserId(userSessionDTO.getId());


        BuildingDomain buildingDomainOne =null;
        if (StringUtils.isNotBlank(apiBuildingDto.getId())){
             buildingDomainOne = buildingReposity.findOne(apiBuildingDto.getId());
            if (buildingDomainOne == null) {
                return new ResDto(Const.SERVER_ERROR, "楼宇不存在");
            }
            //逻辑删除
            if (CommonDbConst.DB_DELETE_LOGICAL.equals(buildingDomainOne.getStatus())){
                return new ResDto(Const.SERVER_ERROR, "楼宇已被删除");
            }
        }
        if (StringUtils.isNotBlank(apiBuildingDto.getUpdateUserId())) {
            UserInfo one = userInfoRepository.findOne(apiBuildingDto.getUpdateUserId());
            if (one == null) {
               return new ResDto(Const.SERVER_ERROR,"更新人不存在");
            }
        }

        if (StringUtils.isNotBlank(apiBuildingDto.getBuildingName())) {
            List<BuildingDomain> buildingDomainExistList = buildingReposity.findAllByBuildingNameAndStatus(apiBuildingDto.getBuildingName(),CommonDbConst.DB_DELETE_NORMAL);
            for (BuildingDomain buildingDomainExist:buildingDomainExistList) {
                if (buildingDomainExist != null) {
                    if (CommonDbConst.DB_DELETE_NORMAL.equals(buildingDomainExist.getStatus())&&!buildingDomainExist.getId().equals(apiBuildingDto.getId())){
                        return new ResDto(Const.SERVER_ERROR, "楼宇名称已存在");
                    }

                }
            }
        }
        BuildingDomain buildingDomain = BeanMapper.map(buildingDomainOne, BuildingDomain.class);
        buildingDomain.setBuildingName(apiBuildingDto.getBuildingName());
        buildingDomain.setUpdateUserId(apiBuildingDto.getUpdateUserId());
        buildingDomain.setGmtModified(new Date());

        try {
            BuildingDomain save = buildingReposity.save(buildingDomain);
            if (save==null){
                return new ResDto(Const.SERVER_ERROR,"楼宇记录修改失败");
            }
            //更新用户负责表
            List<UserLaboratory> allUserManagerByLabBuildingId = userLaboratoryRepository.findAllByLabBuildingId(buildingDomain.getId());
            for (UserLaboratory userLaboratory: allUserManagerByLabBuildingId){
                userLaboratory.setLabBuildingName(apiBuildingDto.getBuildingName());
            }
            userLaboratoryRepository.save(allUserManagerByLabBuildingId);
            //更新实验室表
            List<LaboratoryDomain> allLabByBuildingId = laboratoryRepository.findAllByBuildingId(buildingDomain.getId());
            for (LaboratoryDomain laboratoryDomain:allLabByBuildingId) {
                laboratoryDomain.setBuildingName(apiBuildingDto.getBuildingName());
            }

            laboratoryRepository.save(allLabByBuildingId);



        } catch (Exception e) {
            e.printStackTrace();
            logger.error("修改楼宇信息异常：{}", e);
            return new ResDto(Const.SERVER_ERROR,"楼宇记录修改失败");
        }


        return new ResDto(Const.SUCCESS,"楼宇信息修改成功");
    }

    @Override
    public ResDto geteBuildingDetail(String id) {
        BuildingDomain buildingDomainOne =null;
        if (StringUtils.isNotBlank(id)){
            buildingDomainOne = buildingReposity.findOne(id);
            if (buildingDomainOne == null) {
                return new ResDto(Const.SERVER_ERROR, "楼宇不存在");
            }
            //逻辑删除
            if (CommonDbConst.DB_DELETE_LOGICAL.equals(buildingDomainOne.getStatus())){
                return new ResDto(Const.SERVER_ERROR, "楼宇已被删除");
            }
        }
        ApiBuildingDto apiBuildingDto = BeanMapper.map(buildingDomainOne, ApiBuildingDto.class);
        String data = JsonMapper.defaultMapper().toJson(apiBuildingDto);

        return new ResDto(ConstEum.SUCCESS,data);
    }

    @Override
    public ResDto deleteBuilding(String  id) {

        BuildingDomain buildingDomainOne =null;
        if (StringUtils.isNotBlank(id)){
            buildingDomainOne = buildingReposity.findOne(id);
            if (buildingDomainOne == null) {
                return new ResDto(Const.SERVER_ERROR, "楼宇不存在");
            }
        }
        List<LaboratoryDomain> buildingList = laboratoryRepository.findAllByBuildingIdAndStatus(buildingDomainOne.getId(),CommonDbConst.DB_DELETE_NORMAL);
        if (!buildingList.isEmpty()){
            return new ResDto(Const.SERVER_ERROR,"该楼宇存在实验室，请先删除该楼宇下实验室");
        }


        try {
            //逻辑删除
            buildingDomainOne.setStatus(CommonDbConst.DB_DELETE_LOGICAL);
            buildingReposity.save(buildingDomainOne);

//            buildingReposity.delete(id);

        } catch (Exception e) {
            e.printStackTrace();
            logger.error("删除楼宇信息异常：{}", e);
            return new ResDto(Const.SERVER_ERROR, "删除楼宇信息异常");
        }


        return new ResDto(Const.SUCCESS,"删除成功");
    }

    @Override
    public ResDto getBuildingListPage(FrontPage page) {
        Integer pageSize = page.getSize();
        Integer pageNum = page.getPage();
        BuildingQuery buildingQuery;
        //2.Map conditionMap
        Map<String, Object> conditionMap = page.getCondition();
        if (null == conditionMap || conditionMap.isEmpty()) {

            buildingQuery = new BuildingQuery();
        } else {
            String conditionJson = JsonMapper.defaultMapper().toJson(conditionMap);
            ApiBuildingDto dto = JsonMapper.defaultMapper().fromJson(conditionJson, ApiBuildingDto.class);
            buildingQuery = BeanMapper.map(dto, BuildingQuery.class);
        }
        String order="DESC";
        if (!StringUtils.isEmpty(page.getOrder())){
            if ("ASC".equals(page.getOrder().toUpperCase())){
                order="ASC";
            }
        }
        String prop = "gmt_created";
        if (!StringUtils.isEmpty(page.getProp())){
            prop=page.getProp();
        }
        //设置查询条件
        Pageable pageRequest = new PageRequest(pageNum - 1, pageSize, new Sort(Sort.Direction.fromString(order), prop));
        //6.用MongoManager去查询的数据
        //状态正常
        buildingQuery.setStatus(CommonDbConst.DB_DELETE_NORMAL);
        Page<BuildingDomain> pageResult = mongoManager.findPage(buildingQuery, pageRequest, BuildingDomain.class);


        ResDto resDto = new ResDto(ConstEum.SUCCESS);
        ResDtoUtil.defaultUtil().pageDomainDtoToFrontDto(resDto, pageResult, ApiBuildingDto.class, page);




        return resDto;
    }

    @Override
    public ResDto getBuildingList() {

        List<BuildingDomain> all = null;
        String data = null;
        try {
            all = buildingReposity.findAllByStatus(CommonDbConst.DB_DELETE_NORMAL);
            List<ApiBuildingDto> apiBuildingDtos = BeanMapper.mapList(all, ApiBuildingDto.class);
            data = JsonMapper.defaultMapper().toJson(apiBuildingDtos);
        } catch (Exception e) {
            e.printStackTrace();
            new ResDto(Const.SERVER_ERROR,"获取楼宇信息失败");
        }

        return new ResDto(ConstEum.SUCCESS,data);
    }
}
